package com.heimdallr.rbac.user.dao.impl;

import com.heimdallr.rbac.permission.dao.PermissionDao;
import com.heimdallr.rbac.permission.entity.GroupEntity;
import com.heimdallr.rbac.permission.entity.RoleEntity;
import com.heimdallr.rbac.permission.entity.UserEntity;
import com.heimdallr.rbac.user.dao.UserDao;
import com.heimdallr.util.AppUtils;
import com.heimdallr.util.RedisKey;
import com.heimdallr.util.SerializationUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.io.UnsupportedEncodingException;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * @author user
 */
@Repository(value="userDaoImpl")
public class UserDaoImpl implements UserDao {

	@Autowired
    private StringRedisTemplate redisTemplate;
	@Autowired
    private PermissionDao permissionDao;

	@Override
	public List<UserEntity>  getUserList(Map<String,Object> paraMap){
		
		String username = (String) paraMap.get("username");
		String status = (String) paraMap.get("status");
		String groups = (String) paraMap.get("groups");

        List<Object> redisResult = redisTemplate.opsForHash().values(RedisKey.userEntity.name());

        List<UserEntity> result = new ArrayList<>();

        for(Object redisStr : redisResult){

            UserEntity userEntity = null;

            try {
                userEntity = (UserEntity) SerializationUtils.jdkdeserialize(redisStr.toString().getBytes(SerializationUtils.charsetCode));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            if(userEntity!=null){
                result.add(userEntity);
            }

        }//end foreach

        if(AppUtils.isNotNull(username)){
            result = result.stream().filter(fi->fi.getUserName().startsWith(username)).collect(Collectors.toList());
        }

        if(AppUtils.isNotNull(status)&&!"-1".equals(status)){
            result = result.stream().filter(fi->status.equals(fi.getStatus()+"")).collect(Collectors.toList());
        }

        if(AppUtils.isNotNull(groups)&&!"-1".equals(groups)){
            result = result.stream().filter(fi->groups.equals(fi.getGroupId()+"")).collect(Collectors.toList());
        }


        return result;
	}

	@Override
	public UserEntity getByUserName(String userName){

        UserEntity userEntity = null;

        if(redisTemplate.opsForHash().hasKey(RedisKey.userEntity.name(),userName)){

            String cache = (String) redisTemplate.opsForHash().get(RedisKey.userEntity.name(),userName);

            try {
                userEntity = (UserEntity) SerializationUtils.jdkdeserialize(cache.getBytes(SerializationUtils.charsetCode));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

        }

        userEntity.setGroupEntity(getGroupEntityById(userEntity.getGroupId()));

        return userEntity;
	}

	@Override
    public void saveUserEntity(UserEntity userEntity){

        try {
            String redisStr =  new String(SerializationUtils.jdkserialize(userEntity),SerializationUtils.charsetCode);
            redisTemplate.opsForHash().put(RedisKey.userEntity.name(),userEntity.getUserName(),redisStr);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

    }

    @Override
    public int updateUserEntity(String username, String nickname, String password){

	    UserEntity userEntity = getByUserName(username);

	    userEntity.setNickName(nickname);
	    userEntity.setPassword(password);
	    saveUserEntity(userEntity);
	    return  1;
    }

    @Override
    public GroupEntity getGroupEntityById(int id){

        GroupEntity groupEntity = null;

        if(redisTemplate.opsForHash().hasKey(RedisKey.groupEntity.name(),id+"")){

            String cache = (String) redisTemplate.opsForHash().get(RedisKey.groupEntity.name(),id+"");

            try {
                groupEntity = (GroupEntity) SerializationUtils.jdkdeserialize(cache.getBytes(SerializationUtils.charsetCode));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

        }

        List<RoleEntity> roleEntityList = new ArrayList<>();
        groupEntity.getRoleIdList().forEach(roleId->{
            RoleEntity roleEntity = permissionDao.getRoleEntityById(roleId);
            roleEntityList.add(roleEntity);
        });

        groupEntity.setRoleEntityList(roleEntityList);

        return groupEntity;
    }

	@Override
	public List<GroupEntity> getAllUserGroups() {

        List<Object> redisResult = redisTemplate.opsForHash().values(RedisKey.groupEntity.name());

        List<GroupEntity> result = new ArrayList<>();

        for(Object redisStr : redisResult){

            GroupEntity entity = null;

            try {
                entity = (GroupEntity) SerializationUtils.jdkdeserialize(redisStr.toString().getBytes(SerializationUtils.charsetCode));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            if(entity!=null){
                result.add(entity);
            }

        }//end foreach

        return result;
    }

    @Override
    public int uptUserGroup(String userName,Integer groupId){

        UserEntity userEntity = getByUserName(userName);

        userEntity.setGroupId(groupId);
        saveUserEntity(userEntity);
        return  1;
    }



}
